package com.springboot.ftp.config;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.net.SocketException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description ftp工具类
 */
@Slf4j
public class FtpTools {
    //FTP服务器IP地址
    public final static String FTP_HOST = "127.0.0.1";

    //FTP服务器端口
    public final static int FTP_PORT = 21;

    //FTP服务器用户名
    public final static String FTP_USER = "admin";

    //密码
    public final static String FTP_PASSWORD = "admin";

    /**
     * Description: 向FTP服务器上传文件
     *
     * @param path     FTP服务器保存目录
     * @param filename 上传到FTP服务器上的文件名
     * @param input    输入流
     * @return 成功返回true，否则返回false *
     * @Version 1.0
     */
    @SneakyThrows(IOException.class)
    public static boolean uploadFile(String path, String filename, InputStream input) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        ftp.setControlEncoding("GBK");
        try {
            int reply;
            // 连接FTP服务器
            ftp.connect(FTP_HOST, FTP_PORT);
            // 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            // 登录
            ftp.login(FTP_USER, FTP_PASSWORD);
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.makeDirectory(path);
            ftp.changeWorkingDirectory(path);
            ftp.storeFile(filename, input);
            input.close();
            ftp.logout();
            success = true;
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * 从服务器的FTP路径下读取文件
     *
     * @param ftpPath
     * @return
     */
    public static InputStream readFileFromFTP(String ftpPath, String fileName) {
        StringBuffer resultBuffer = new StringBuffer();
        BufferedOutputStream output;
        InputStream in = null;
        FTPClient ftpClient = null;
        log.info("开始从绝对路径：" + ftpPath + "读取文件!");
        try {
            ftpClient = FtpTools.getFTPClient(FTP_HOST, FTP_PORT, FTP_USER, FTP_PASSWORD);
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.makeDirectory("test");
            ftpClient.changeWorkingDirectory(ftpPath);
            FTPFile[] ftpFiles = ftpClient.listFiles("/admin"); //获取admin目录下的文件
            List<String> fileNames = Arrays.stream(ftpFiles).map(FTPFile::getName).collect(Collectors.toList());
            fileNames.forEach(System.out::print);
            for (FTPFile ftpFile : ftpFiles) {
                File file = new File("D:\\app\\ftp\\"+ftpFile.getName());
                output = new BufferedOutputStream(new FileOutputStream(file));
                ftpClient.retrieveFile(ftpFile.getName(), output);
            }

            in = ftpClient.retrieveFileStream(fileName);
        } catch (FileNotFoundException e) {
            log.error("没有找到" + ftpPath + "文件");
            e.printStackTrace();
        } catch (SocketException e) {
            log.error("连接FTP失败!");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件读取错误!");
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return in;
    }

    /**
     * 获取FTPClient对象
     *
     * @param ftpHost     FTP主机服务器
     * @param ftpPassword FTP 登录密码
     * @param ftpUserName FTP登录用户名
     * @param ftpPort     FTP端口 默认为21
     * @return
     */
    public static FTPClient getFTPClient(String ftpHost, int ftpPort,
                                         String ftpUserName, String ftpPassword) {
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                log.info("未连接到FTP,用户名或密码错误!");
                ftpClient.disconnect();
            } else {
                log.info("FTP连接成功!");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            log.info("FTP的IP地址可能错误，请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            log.info("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }
      /**
     * 删除ftp上的文件
     *
     * @param ftpFileName
     * @return true || false
     */
    public static boolean removeFile(String ftpFileName) {
        boolean flag = false;
        log.info("待删除文件：{}", ftpFileName);
        FTPClient ftpClient = null;
        try {
            ftpClient = FtpTools.getFTPClient(FTP_HOST, FTP_PORT, FTP_USER, FTP_PASSWORD);
            ftpFileName = new String(ftpFileName.getBytes("GBK"), "iso-8859-1");
            flag = ftpClient.deleteFile(ftpFileName);
            log.info("删除文件：{}"
                , flag ? "成功" : "失败");
            return flag;
        } catch (IOException e) {
            log.error("删除文件失败！" + e);
            return false;
        }
    }
}